import uuid

from conf.neo4j_cnx import NeoCnxPool
from web.const import StatusCode

neo_cnx = NeoCnxPool()


def query_entity_type_item():
    with neo_cnx.get_session() as session:
        query = (
            'MATCH (n:EntityType) '
            'RETURN n.name AS name, n.view_name AS view_name')
        results = session.run(query)
        entity_type_item = {}
        for record in results:
            entity_type_item[record['name']] = record['view_name']
        return entity_type_item


def entity_view(label):
    if type(label) is str:
        return query_entity_type_item()[label]
    if type(label) is list:
        view_list = []
        for i in label:
            view_list.append(query_entity_type_item()[i])
        return view_list


def entity_model(label):
    if type(label) is str:
        for key, value in query_entity_type_item().items():
            if value == label:
                return key
    if type(label) is list:
        view_list = []
        for key, value in query_entity_type_item().items():
            for i in label:
                if value == i:
                    view_list.append(key)


class EntityType:

    def create_entity_type(self, name, desc=''):
        if not self.does_node_exists(name):
            with neo_cnx.get_session() as session:
                query = (
                    'MERGE (n:EntityType {name: $name, uid: $uid, view_name: $view_name, desc: $desc})'
                )
                session.run(query, name=name, view_name=name, desc=desc, uid=str(uuid.uuid4()))
        else:
            return {'status': StatusCode.ENTITY_TYPE_REPEATE,
                    'message': ''}

    def alter_entity_type_name(self, old_name, new_name, desc):
        with neo_cnx.get_session() as session:
            query = (
                'MATCH (n:EntityType {view_name: $old_name}) '
                'SET n.view_name = $new_name, n.desc = $desc'
            )
            session.run(query, old_name=old_name, new_name=new_name, desc=desc)

    def does_node_exists(self, name):
        with neo_cnx.get_session() as session:
            query = (
                'MATCH (n:EntityType {name: $name}) '
                'RETURN count(n) AS n_count'
            )
            results = session.run(query, name=name, uid=str(uuid.uuid4()))
            results = [record['n_count'] for record in results][0]
            if results > 0:
                return True
            else:
                return False

    def init_entity_type(self, entity_type_list):
        for entity_name in entity_type_list:
            self.create_entity_type(entity_name)

    def query_entity_type(self):
        with neo_cnx.get_session() as session:
            query = (
                'MATCH (n:EntityType) '
                'RETURN n.view_name AS view_name')
            results = session.run(query)
            results = [record['view_name'] for record in results.data()]
            return results

    def delete_entity_type(self, name):
        label = entity_model(name)
        with neo_cnx.get_session() as session:
            query = (
                        'MATCH (n:%d) '
                        'RETURN count(n) AS count'
                    ) % label
            results = session.run(query)
            for record in results:
                if record['count'] > 0:
                    return False
                else:
                    query = (
                        'MATCH (n:EntityType {view_name: $name}) '
                        'DETACH DELETE n')
                    session.run(query, name=name)


if __name__ == '__main__':
    entity_type_app = EntityType()
    entity_type_app.init_entity_type(
        entity_type_list=['疾病', '症候', '影像学检查', '实验室检查', '病原体',
                          '解剖部位', '药物', '治疗方式'])
    entity_type_list = entity_type_app.query_entity_type()
    print(entity_type_list)
